home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Cream of the Crop 1
/
Cream of the Crop 1.iso
/
PROGRAM
/
WEDITS22.ARJ
/
WELINE.PAS
< prev
next >
Wrap
Pascal/Delphi Source File
|
1991-08-13
|
7KB
|
267 lines
UNIT WELine;
{ -- This is the Line Handling unit for WWIVEdit 2.2
-- Last Modified : 8/13/91
-- Written By:
-- Adam Caldwell
--
-- This code is limited public domain (see WWIVEDIT.PAS for details)
--
-- Known errors: None
--
-- Planned Enhancements: None
--
--}
{$R-,V-,S+,B-,E-,N-} { These Optomize things as much as possible }
INTERFACE
USES WEVars;
PROCEDURE MakeString(VAR s:LineType; ch,col:char);
FUNCTION Len(LineNum : integer):byte;
FUNCTION Character(lineNum,Column:integer):char;
PROCEDURE LDelete(LineNum,index,length:integer);
FUNCTION Color(VAR s:linetype; p:integer):char;
PROCEDURE LInsert(s:LineType; LineNum, index:integer);
PROCEDURE StripEnd(LineNum:integer);
PROCEDURE WordWrap(VAR s1:linetype; VAR s2:linetype; minx:integer);
PROCEDURE InsertLine(before:integer; s:linetype);
PROCEDURE DeleteLine(n:integer);
FUNCTION FirstDiff(s1,s2:LineType):integer;
PROCEDURE Reformat(n:integer; movecursor:boolean);
PROCEDURE InitLine(VAR s:LineType);
IMPLEMENTATION
PROCEDURE InitLine(VAR s:LineType);
{ Initializes a line to an empty string and sets the color attributes to 0 }
VAR x:integer;
BEGIN
s.l:='';
s.c:='';
s.HardCR:=TRUE;
END;
PROCEDURE MakeString(VAR s:LineType; ch,col:char);
{ Makes a "Line" of one charcter with the given color attribute }
BEGIN
s.l[0]:=#1;
s.c[0]:=#1;
s.l[1]:=ch;
s.c[1]:=col;
END;
FUNCTION Len(LineNum : integer):byte;
{ Returns the length of the given LineNum }
BEGIN
Len:=length(Line[lineNum]^.l)
END;
FUNCTION Character(lineNum,Column:integer):char;
{ Returns the Character at the given Column on the Given Line }
BEGIN
IF len(LineNum)>0 THEN Character:=Line[LineNum]^.l[column] ELSE Character:=#0
END;
PROCEDURE LDelete(LineNum,index,length:integer);
{ Deletes from the given LineNum starting at index, length # of characters }
VAR
x: integer;
BEGIN
delete(Line[LineNum]^.l,index,length);
delete(Line[LineNum]^.c,index,length);
END;
FUNCTION Color(VAR s:linetype; p:integer):char;
{ Returns the color attribute of the p'th character on the "line" S }
BEGIN
Color := s.c[p]
END;
PROCEDURE LInsert(s:LineType; LineNum, index:integer);
{ inserts the given string onto the given LineNum at the given index }
VAR
x:integer;
t:LineType;
clr : char;
BEGIN
{ Pad the line with blanks if needed }
IF NOT InsertMode
THEN x:=index+length(s.l)-1
ELSE x:=index-1;
WHILE (x>len(LineNum)) DO
BEGIN
IF len(LineNum)<1
THEN clr:=CurrentColor
ELSE clr:=Color(Line[LineNum]^,Len(LineNum));
MakeString(t,' ',clr);
insert(t.c,Line[LineNum]^.c,length(Line[LineNum]^.c)+1);
insert(t.l,Line[LineNum]^.l,length(Line[LineNum]^.c)+1);
END;
IF InsertMode THEN
BEGIN
insert(s.l,Line[LineNum]^.l,index);
insert(s.c,Line[LineNum]^.c,index);
END
ELSE
FOR x:=index TO index+length(s.l)-1 DO
BEGIN
Line[LineNum]^.l[x]:=s.l[x-index+1];
Line[LineNum]^.c[x]:=s.c[x-index+1];
END;
END;
PROCEDURE StripEnd(LineNum:integer);
{ Strips off the end of the given LineNum }
BEGIN
WHILE Character(LineNum,len(LineNum))=' ' DO
LDelete(LineNum,len(LineNum),1);
END;
PROCEDURE WordWrap(VAR s1:linetype; VAR s2:linetype; minx:integer);
{ strips off the last word(s) in s1 and stores it in S2 }
VAR i,x:integer;
BEGIN
IF minx>=Length(s1.l) THEN minx:=0;
x:=length(s1.l); { point X to the end of the orignal line }
IF x>LineLen THEN x:=LineLen; { Make sure that all extra is taken off }
WHILE (x>minx) AND (NOT (s1.l[x]=' ')) DO { Go until it finds a space or there's nothing left }
dec(x);
IF x=0 THEN x:=LineLen;
s2.l := copy(s1.l,x+1,length(s1.l)-x); { copy the string part of it }
s2.c := copy(s1.c,x+1,length(s1.c)-x); { copy the color part of it }
delete(s1.l,length(s1.l)-length(s2.l)+1,length(s2.l));
delete(s1.c,length(s1.c)-length(s2.c)+1,length(s2.c));
END;
PROCEDURE InsertLine(before:integer; s:linetype);
{ inserts the line s on the line before the line pointed to by before }
VAR x:integer;
BEGIN
IF before<=BlockStart THEN inc(blockStart);
IF before<=BlockEnd THEN inc(blockEnd);
Dispose(Line[MaxLines]);
FOR x:=MaxLines DOWNTO before DO
Line[x]:=Line[x-1];
New(Line[Before]);
Line[before]^:=s;
IF before>Highline THEN
Highline:=before+1
ELSE
Inc(Highline);
END;
FUNCTION FirstDiff(s1,s2:LineType):integer;
{ Compares the two lines until it finds a difference in either the characters
or the colors }
VAR
x:integer;
EndPoint:integer;
BEGIN
IF (s1.l='') or (s2.l='') THEN FirstDiff:=1
ELSE BEGIN
IF length(s1.l)>length(s2.l) THEN EndPoint:=length(s2.l)
ELSE EndPoint := length(s1.l);
x:=1;
WHILE (x<=EndPoint) AND (s1.l[x]=s2.l[x]) AND (s1.c[x]=s2.c[x]) DO
inc(x);
FirstDiff:=x;
END
END;
PROCEDURE DeleteLine(n:integer);
{ Removes the given line number }
VAR
x:integer;
Temp : pointer;
BEGIN
IF n<BlockStart THEN Dec(BlockStart);
IF n<BlockEnd THEN Dec(BlockEnd);
temp:=Line[n];
FOR x:=n TO MaxLines-1 DO
Line[x]:=Line[x+1];
Line[MaxLines]:=temp;
InitLine(Line[MaxLines]^);
IF n>Highline THEN
Highline:=n
ELSE
dec(highline);
END;
PROCEDURE Reformat(n:integer; MoveCursor:boolean);
{ Reformats the text, starting at the given line. }
{ -- Majorly changed since 2.1 to take into account where the hard Carriage
returns are. }
VAR
flag : boolean;
t : LineType;
l : integer;
BEGIN
InitLine(t); { Initialize a temporary line }
flag:=MoveCursor;
IF Len(n)>LineLen THEN { Split off last word onto new line }
BEGIN
flag:=cx>LineLen;
StripEnd(n); { Erase any blank characters at the end of the line }
InsertLine(n+1,t); { Insert a blank line }
IF Len(n)>LineLen THEN{ If this line is too long, then wordwrap }
BEGIN
WordWrap(Line[n]^,Line[n+1]^,cx);
StripEnd(n);
END;
IF flag THEN BEGIN
inc(cy);
cx:=len(cy);
END ELSE Line[n+1]^.hardCR:=false;
Line[n]^.HardCR:=false;
inc(n);
END;
WHILE NOT Line[n]^.HardCR DO
BEGIN
{ Drain; { Drain off any keystokes waiting }
flag:=Line[n]^.l[len(n)]<>' '; { True if line will need space attached }
l:=LineLen-Len(n); { Number of character this line can accept }
IF flag THEN dec(l);
IF l>Len(n+1) THEN BEGIN { If the next line is less characters than }
IF flag THEN { can fit, then just add the whole line }
LInsert(Line[n+1]^,n,len(n)+2)
ELSE
LInsert(Line[n+1]^,n,len(n)+1);
Line[n]^.HardCR:=Line[n+1]^.HardCR;
DeleteLine(n+1); { Delete that old part that was just added }
END
ELSE BEGIN { otherwise, add one word at a time }
WHILE (l>0) AND (Line[n+1]^.l[l]<>' ') DO
dec(l);
t.l:=copy(Line[n+1]^.l,1,l-1);
t.c:=copy(Line[n+1]^.c,1,l-1);
Ldelete(n+1,1,l);
IF t.l<>'' THEN
IF flag THEN
Linsert(t,n,len(n)+2)
ELSE
Linsert(t,n,len(n)+1);
inc(n);
END;
END;
END;
END.